#pragma once
#ifndef VISUALIZER_H
#define VISUALIZER_H

#ifndef NOSTDAFX
#include "StdAfx.h"
#endif

#include <cstddef>
#include "Element.h"
#include "DynamicData.h"
#include "Coord.h"

#ifdef PLUGIN_EXPORT
#define PLUGIN_API __declspec(dllexport)
#else
#define PLUGIN_API __declspec(dllimport)
#endif

// TODO: "=0" durch #define PLUGIN_IMPLEMENT (o.�.) ersetzen

struct CostumeMatrix
{
private:
	CostumeMatrix();
	~CostumeMatrix();
public:
	CostumeMatrix* multiply(CostumeMatrix* pOut, CostumeMatrix* pOp1, CostumeMatrix* pOp2) const;
 
	void Set(const Coord1D x, const Coord1D y, const float sx, const float sy, const float angle, const Coord1D centerX, const Coord1D centerY);

	const Vloat& GetX() const;		///< the returned references must always be valid
	const Vloat& GetY() const;
	const Vloat& GetAngle() const;
	const Vloat& GetXScale() const;
	const Vloat& GetYScale() const;
	void SetX(const Vloat);
	void SetY(const Vloat);
	void SetAngle(const Vloat);
	void SetXScale(const Vloat);
	void SetYScale(const Vloat);

	void* operator new (std::size_t s);
	void operator delete (void* pMat);
};

struct CostumeRenderData;
struct CostumeImage;
/**
 * Where is a resizing function?
 * The Visualizer has to look at the root-Element's width and high
 * The root-elements 'image' parameter is the rendertarget for everything.
 * TODO: Element-resize invokes CostumeImage-resize. This should only occur on enlargement (and reserve some extra-size?).
 *		 This als means u and v coordinates have to be wrapped, inside the Visualizer.
 */
class /*PLUGIN_API*/ Visualizer
{
public:
	virtual void Init(VlareHashMap properties) = 0;
	virtual void AcquireResources() = 0;
	virtual void FreeResources() = 0;
	virtual void Free() = 0;

	virtual void	RegisterElement(Element *const pElem) = 0;
	virtual void	UnregisterElement(Element *const pElem) = 0;

	virtual void	PreDraw() = 0;	///< Called once before Drawing
	virtual void	DrawElement(const Element *const pElem, CostumeImage *const pImg) = 0;	///< Called once for every Element to be drawn!
	virtual void	PostDraw() = 0;	///< Called once after Drawing

	
			/// allocates memory for CostumeMatrix
//	virtual bool	AllocMat(CostumeMatrix* &pOut) = 0;
			/// frees CostumeMatrix
//	virtual bool	FreeMat(CostumeMatrix* &pIn) = 0;
			/// copys CostumeMatrix
//	virtual bool	CopyMat(CostumeMatrix* pSet, const CostumeMatrix* pToCopy) = 0;
			/// fills CostumeMatrix and calculates it from the raw input data
//	virtual bool	MakeMat(CostumeMatrix* pOut, const Coord1D x, const Coord1D y, const float sx, const float sy, const float angle, const Coord1D centerX, const Coord1D centerY) = 0;
			/// multiplies two CostumeMatrices (used to set an element as the child of an other)
//	virtual bool	MultMat(CostumeMatrix* pResult, const CostumeMatrix* const pOp1, const CostumeMatrix* const pOp2) = 0;
			/// used to get a points position inside an element
//	virtual bool	TransformPoints(Coord2D_si* const pResults, const Coord2D_si* const pPoints, const unsigned int uiNoOfP, const CostumeMatrix* const pFrom, const CostumeMat* const pTo) = 0;
			/// 
//	virtual bool	CheckPointsOver(CollisionInfo*	const pResults, const ElementPaper* const pRD, Coord2D_si* const pPoints, const unsigned int uiNoOfP) = 0;

};

#endif
